iT邦幫忙

2023 iThome 鐵人賽

DAY 22
0
Software Development

Java基礎筆記系列 第 25

Java 的Synchronization與Locks

  • 分享至 

  • xImage
  •  

在多執行緒的環境下,多個執行緒可能會同時存取、共享資源,若是沒有正確的使其同步,會導致不好的結果,例如變數或資料結構。如果沒有正確的同步,這可能導致資料破壞或不可預期的結果。

多執行緒同步Synchronization

多執行緒的同步Synchronization是非常重要的概念,目的在於控制「每次只能有一個執行緒使用同一份資料」,避免多個執行緒同時存取同一份資源,造成衝突或重複修改。
危險區域是指在多執行緒環境下,同時存取可能產生不正確的區域。
假設在圖書館自助借書時,若只剩下一本書,同時有兩名讀者都想借,他們於自助借書機器看到都有剩一本,並同時按下借書顯示成功,但實際只剩一本書,此時就有衝突。此為危險區域。

//同步方法。表示當一個執行緒進入此方法時,其他任何執行緒都不能執行此方法。
public synchronized void myMethod() {
    // 危險區域
}
//同步區塊。在特定的程式區塊使用 synchronized。
public void myMethod() {
    synchronized(this) { //當執行緒擁有這個鎖時,其他執行緒不能進入這個 區塊。
        // 危險區域
    }
}
//同步靜態方法。整個類別本身用作鎖。
public static synchronized void myStaticMethod() {
    // 危險區域
}

鎖Lock

鎖是一種同步機制,用於確保同一時間只有一個執行緒可以執行特定的程式區塊或資源。
ReentrantLock是Java中提供的一種可重入鎖,它具有與synchronized相似的功能,但提供了更高的靈活性。

  • 排他性:當一個執行緒擁有鎖時,其他執行緒無法獲得其鎖,直至持有鎖的執行緒釋放鎖。
  • 可重入性:若一個執行緒已擁有某個鎖,可再次獲得同一個鎖。
  • 死鎖:當兩個以上的執行緒相互等待對方釋放鎖,會導致都無法進行。
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

public class LockExample {
    private final Lock lock = new ReentrantLock();

    public void myMethod() {
        lock.lock();  // 鎖住
        try {
            // 危險區域
        } finally {
            lock.unlock();  // 釋放鎖
        }
    }
}

注意事項

  • 死鎖解決方法:例如:超時機制、鎖排序、鎖超時等。
  • 適時釋放資源:使用synchronized和鎖時,要注意在適當的時機釋放資源,避免其他執行緒無法獲得資源的情況。
  • 衡量效率問題:過度使用同步會導致系統效能下降,因此在設計時,要衡量。

上一篇
Java 多執行緒Thread vs. Runnable
下一篇
Java的wait(), notify()和 notifyAll()
系列文
Java基礎筆記30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言